1 package org.apache.lucene.util;
2
3 import java.util.ArrayList;
4 import java.util.HashSet;
5 import java.util.List;
6 import java.util.concurrent.atomic.AtomicLong;
7 import org.junit.Before;
8 import org.junit.Test;
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public class TestRecyclingByteBlockAllocator extends LuceneTestCase {
31
32
33
34 @Override
35 @Before
36 public void setUp() throws Exception {
37 super.setUp();
38 }
39
40 private RecyclingByteBlockAllocator newAllocator() {
41 return new RecyclingByteBlockAllocator(1 << (2 + random().nextInt(15)),
42 random().nextInt(97), Counter.newCounter());
43 }
44
45 @Test
46 public void testAllocate() {
47 RecyclingByteBlockAllocator allocator = newAllocator();
48 HashSet<byte[]> set = new HashSet<>();
49 byte[] block = allocator.getByteBlock();
50 set.add(block);
51 assertNotNull(block);
52 final int size = block.length;
53
54 int num = atLeast(97);
55 for (int i = 0; i < num; i++) {
56 block = allocator.getByteBlock();
57 assertNotNull(block);
58 assertEquals(size, block.length);
59 assertTrue("block is returned twice", set.add(block));
60 assertEquals(size * (i + 2), allocator.bytesUsed());
61 assertEquals(0, allocator.numBufferedBlocks());
62 }
63 }
64
65 @Test
66 public void testAllocateAndRecycle() {
67 RecyclingByteBlockAllocator allocator = newAllocator();
68 HashSet<byte[]> allocated = new HashSet<>();
69
70 byte[] block = allocator.getByteBlock();
71 allocated.add(block);
72 assertNotNull(block);
73 final int size = block.length;
74
75 int numIters = atLeast(97);
76 for (int i = 0; i < numIters; i++) {
77 int num = 1 + random().nextInt(39);
78 for (int j = 0; j < num; j++) {
79 block = allocator.getByteBlock();
80 assertNotNull(block);
81 assertEquals(size, block.length);
82 assertTrue("block is returned twice", allocated.add(block));
83 assertEquals(size * (allocated.size() + allocator.numBufferedBlocks()), allocator
84 .bytesUsed());
85 }
86 byte[][] array = allocated.toArray(new byte[0][]);
87 int begin = random().nextInt(array.length);
88 int end = begin + random().nextInt(array.length - begin);
89 List<byte[]> selected = new ArrayList<>();
90 for (int j = begin; j < end; j++) {
91 selected.add(array[j]);
92 }
93 allocator.recycleByteBlocks(array, begin, end);
94 for (int j = begin; j < end; j++) {
95 assertNull(array[j]);
96 byte[] b = selected.remove(0);
97 assertTrue(allocated.remove(b));
98 }
99 }
100 }
101
102 @Test
103 public void testAllocateAndFree() {
104 RecyclingByteBlockAllocator allocator = newAllocator();
105 HashSet<byte[]> allocated = new HashSet<>();
106 int freeButAllocated = 0;
107 byte[] block = allocator.getByteBlock();
108 allocated.add(block);
109 assertNotNull(block);
110 final int size = block.length;
111
112 int numIters = atLeast(97);
113 for (int i = 0; i < numIters; i++) {
114 int num = 1 + random().nextInt(39);
115 for (int j = 0; j < num; j++) {
116 block = allocator.getByteBlock();
117 freeButAllocated = Math.max(0, freeButAllocated - 1);
118 assertNotNull(block);
119 assertEquals(size, block.length);
120 assertTrue("block is returned twice", allocated.add(block));
121 assertEquals(size * (allocated.size() + allocator.numBufferedBlocks()),
122 allocator.bytesUsed());
123 }
124
125 byte[][] array = allocated.toArray(new byte[0][]);
126 int begin = random().nextInt(array.length);
127 int end = begin + random().nextInt(array.length - begin);
128 for (int j = begin; j < end; j++) {
129 byte[] b = array[j];
130 assertTrue(allocated.remove(b));
131 }
132 allocator.recycleByteBlocks(array, begin, end);
133 for (int j = begin; j < end; j++) {
134 assertNull(array[j]);
135 }
136
137 int numFreeBlocks = allocator.numBufferedBlocks();
138 int freeBlocks = allocator.freeBlocks(random().nextInt(7 + allocator
139 .maxBufferedBlocks()));
140 assertEquals(allocator.numBufferedBlocks(), numFreeBlocks - freeBlocks);
141 }
142 }
143 }